import base64
import pickle

from django.shortcuts import render

# Create your views here.

# import pickle
# import base64
# cart = {
#     1:{'count':666,'select':True}
# }
#
# dump = pickle.dumps(cart)
# encode = base64.b64encode(dump)
# encode.decode()
#
# decode = base64.b64decode(encode)
#
# pickle.loads(decode)
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from cart.serializers import CartSerializer, CartSKUSerializer, CartSKUIDSerialzier
from goods.models import SKU


class CartAPIView(APIView):

    def perform_authentication(self, request):
        """
        重写父类的用户验证方法,不在进入视图就检查JWT
        """
        pass

    def post(self,request):

        data = request.data

        serilizer = CartSerializer(data = data)
        serilizer.is_valid()

        sku_id = serilizer.validated_data.get("sku_id")
        count = serilizer.validated_data.get("count")
        selected = serilizer.validated_data.get("selected")

        try:
            user = request.user
        except Exception as e:
            user = None

        if user is not None and user.is_authenticated:

            redis_conn = get_redis_connection("cart")
            # redis_conn.hash("cart_%s" %user.id,sku_id,count)
            # redis_conn.hincrby('cart_%s' % user.id, sku_id, count)
            #使用redis的管道
            pl = redis_conn.pipeline()
            pl.hincrby('cart_%s' % user.id, sku_id, count)

            if selected:
                # redis_conn.sadd("cart_selected_%s" %user.id,sku_id)
                pl.sadd('cart_selected_%s' % user.id, sku_id)
            pl.execute()
            return  Response(serilizer.data)

        else:
            cookie_str = request.COOKIES.get("cart")

            if cookie_str is not None:
                decode = base64.b64decode(cookie_str)
                cookie_cart = pickle.loads(decode)
            else:
                cookie_cart = {}

            if sku_id in cookie_cart:

                original_count = cookie_cart[sku_id]['count']
                count += original_count

            cookie_cart[sku_id] = {
                "count":count,
                "selected":selected
            }

            dumps = pickle.dumps(cookie_cart)
            encode =base64.b64encode(dumps)

            response = Response(serilizer.data)
            response.set_cookie("cart",encode.decode())

            return response



    def get(self,request):

        try:
            user = request.user
        except Exception as e:
            user = None

        if user is not None and user.is_authenticated:
            redis_conn = get_redis_connection("cart")
            sku_id_count = redis_conn.hgetall('cart_%s' %user.id)
            selected_ids = redis_conn.smembers("cart_selected_%s" %user.id)

            cookie_cart = {}
            for sku_id,count in sku_id_count.items():
                cookie_cart[int(sku_id)] = {
                    "count":int(count),
                    "selected":sku_id in selected_ids
                }

        else:
            cookie_str = request.COOKIES.get("cart")
            if cookie_str is not None:
                cookie_cart = pickle.loads(base64.b64decode(cookie_str))
            else:
                cookie_cart = {}

        ids = cookie_cart.keys()
        skus = SKU.objects.filter(pk__in = ids)

        for sku in skus:
            sku.count = cookie_cart[sku.id]["count"]
            sku.selected = cookie_cart[sku.id]["selected"]

        serializer = CartSKUSerializer(skus,many=True)

        return Response(serializer.data)


    def put(self,request):

        data = request.data

        serializer = CartSerializer(data=data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.validated_data.get("sku_id")
        count = serializer.validated_data.get("count")
        selected = serializer.validated_data.get("selected")

        try:
            user = request.user
        except Exception as e:
            user = None

        if user is not None and user.is_authenticated:
            redis_conn = get_redis_connection("cart")
            redis_conn.hset('cart_%s' %user.id,sku_id,count)

            if selected:
                redis_conn.sadd("cart_selected_%s" %user.id,sku_id)
            else:
                redis_conn.srem("cart_selected_%s" %user.id,sku_id)
            return  Response(serializer.data)

        else:
            cookie_str = request.COOKIES.get("cart")
            if cookie_str is not None:
                cookie_cart = pickle.loads(base64.b64decode(cookie_str))
            else:
                cookie_cart = {}
            if sku_id in cookie_cart:
                cookie_cart[sku_id] = {
                    "count": count,
                    "selected": selected
                }
            cookie_encode = base64.b64encode(pickle.dumps(cookie_cart))
            response = Response(serializer.data)
            response.set_cookie('cart', cookie_encode.decode())

            return response


    def delete(self,request):

        data = request.data
        serializer = CartSKUIDSerialzier(data=data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.validated_data["sku_id"]
        try:
            user = request.user
        except Exception as e:
            user = None

        if user is not None and user.is_authenticated:
            redis_conn = get_redis_connection("cart")
            redis_conn.hdel("cart_%s" %user.id,sku_id)
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            cookie_str = request.COOKIES.get("cart")
            if cookie_str is not None:
                cookie_cart = pickle.loads(base64.b64decode(cookie_str))
            else:
                cookie_cart = {}
            if sku_id in cookie_cart:
                del cookie_cart[sku_id]

            cookie_encode = base64.b64encode(pickle.dumps(cookie_cart))
            response = Response(status=status.HTTP_204_NO_CONTENT)

            response.set_cookie('cart', cookie_encode.decode())

            return response